import { getCurrentInstance, useSSRContext, onServerPrefetch } from "vue";
import { useRoute } from "vue-router";
import { global } from "./global";

export type SsrInitStore = () => Promise<any> | undefined;
export type SsrInitPiniaState = () => Promise<any>;
export type SsrInitClientPage = (initStore: SsrInitStore) => Promise<any>;
export type SsrStates = Record<string, { ssrRendered: boolean }>;

// 获取pinia的所有状态
export function usePiniaRef() {
	let pinia = getCurrentInstance()!.appContext.config.globalProperties.$pinia;
	return pinia.state;
}

// 重置渲染标记
export function useResetSSRRendered() {
	return (states: SsrStates) => {
		let vals = Object.values(states);
		let ssrRendered = vals.find((e) => e.ssrRendered);
		if (ssrRendered) {
			vals.forEach((e) => (e.ssrRendered = false));
		}
		return ssrRendered;
	};
}

// 自动获取fetch函数
export async function useSsrFetch() {
	return import.meta.env.SSR ? (await import("node-fetch")).default : fetch;
}

// 在服务端保存state
export function useSaveSSRState() {
	if (!import.meta.env.SSR) {
		return () => {};
	}
	let route = useRoute();
	let pinia = usePiniaRef();
	let context = useSSRContext()!;
	return (states: Record<string, { ssrRendered: boolean }>) => {
		Object.values(states).forEach((e) => (e.ssrRendered = true));
		context.ssr_state.state = pinia.value;
		context.ssr_state[route.path] = Object.assign(context.ssr_state[route.path] || {}, states);
		console.log("ssr saved state: " + route.path + " " + Object.keys(states));
	};
}

// 在客户端恢复state
export function restoreSSRState(states: SsrStates) {
	if (import.meta.env.SSR) {
		return;
	}
	let route = useRoute();
	if (global.__ssr_state[route.path]) {
		console.log("restoreSSRState: " + route.path, global.__ssr_state[route.path]);
		Object.entries(states).forEach(([k, s]) => {
			Object.assign(s as Object, global.__ssr_state[route.path][k]);
		});
	}
}

// 在服务端初始化状态并保存
export function saveSSRState(initServerPiniaState: SsrInitStore, states: SsrStates) {
	if (import.meta.env.SSR) {
		let saveState = useSaveSSRState();
		console.log("saveSSRState: ", Object.keys(states));
		onServerPrefetch(async () => {
			console.log("onServerPrefetch: ", Object.keys(states));
			if (initServerPiniaState) {
				let result = await initServerPiniaState();
				console.log("initServerPiniaState: ", Object.keys(states), result);
			}
			saveState(states);
		});
	}
}

// 统一处理服务端、客户端的状态初始化
export function initSSRState(initServerPiniaState: SsrInitPiniaState, initClientPage: SsrInitClientPage, states: SsrStates) {
	const resetSSRRendered = useResetSSRRendered();
	const initStore = () => {
		if (resetSSRRendered(states)) {
			console.log("ssr store inited");
			return;
		}
		return initServerPiniaState && initServerPiniaState();
	};
	saveSSRState(initStore, states);
	restoreSSRState(states);
	if (import.meta.env.SSR || !initClientPage) return;
	initClientPage(initStore);
}
